package com.summer.utils.date;


import org.springframework.util.StringUtils;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 日期类说明
 */
public class AdsDateUtil {
    public static final String formate = "yyyyMMdd";
    public static final String formate2 = "yyyy-MM-dd";
    public static final String formate3 = "yyyy-MM-dd HH:mm:ss";
    public static final String formate4 = "yyyy-MM";
    public static final String formatYYYYMM_CN = "yyyy年MM月";
    public static final String formatYYYYMMdd_CN = "yyyy年MM月dd日";
    public static final String formateYYYYMM = "yyyyMM";
    public static final String formatYYYYMMDDhhmmss = "yyyyMMddHHmmss";
    public static final SimpleDateFormat sf = new SimpleDateFormat(formate2);

    public static Date toDateForYYYYMMddhhmmss(String date) {
        try {

            return new SimpleDateFormat().parse(date);
        } catch (Exception e) {
            return new Date();
        }
    }


    /**
     * <p>2012-07-21 ==>>  201207</p>
     *
     * @param dateStr
     * @return Integer
     */
    public static Integer toIntYYYYMM_fromYYYY_MM_DDString(String dateStr) {
        try {
            if (StringUtils.isEmpty(dateStr)) {
                return null;
            }
            return Integer.valueOf(new SimpleDateFormat(formateYYYYMM).format(new SimpleDateFormat(formate2).parse(dateStr)));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String toStringYYYYMM_CN(int dateInt) {
        try {
            return new SimpleDateFormat(formatYYYYMM_CN).format(new SimpleDateFormat(formateYYYYMM).parse(String.valueOf(dateInt)));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String toStringYYYYMMDD_CN(Date date) {
        try {
            return new SimpleDateFormat(formatYYYYMMdd_CN).format(date);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    public static String toStringYYYYMM_HH_mm_ss(Date date) {
        try {
            return new SimpleDateFormat(formate3).format(date);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String toStringYYYY_MM(Date date) {
        try {
            return new SimpleDateFormat(formate4).format(date);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Date toDateFromYYYYMM_HH_mm_ss_String(String dateString) {
        try {
            return new SimpleDateFormat(formate3).parse(dateString);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Date toDateFromYYYYMMDD_Int(Integer dateInt) {
        try {
            return new SimpleDateFormat(formate).parse(dateInt.toString());
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Date toDateFromYYYYMMDD_String(String dateString) {
        try {
            return new SimpleDateFormat(formate).parse(dateString);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Date toDateFromYYYY_MM_DD(String dateString) {
        try {
            return new SimpleDateFormat(formate2).parse(dateString);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Date toDateFromYYYY_MM_DD(Integer dateInt) {
        try {
            return new SimpleDateFormat(formate2).parse(dateInt.toString());
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static int toInt_YYYYMMDDFromDate(Date date) {
        return Integer.valueOf(new SimpleDateFormat(formate).format(date));
    }

    public static String toStringYYYY_MM_DD(Date date) {
        return new SimpleDateFormat(formate2).format(date);
    }

    public static String toInt_YYYY_MM_DDhh_mm_ss(Date date) {
        try {
            if (date == null) {
                return null;
            }
            return new SimpleDateFormat(formate3).format(date);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String toInt_YYYYMMDDhhmmss(Date date) {
        try {
            if (date == null) {
                return null;
            }
            return new SimpleDateFormat(formatYYYYMMDDhhmmss).format(date);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Date dateAddDays(int days, Date date) {
        long time = 1000L * 24 * 60 * 60 * days;
        date.setTime(date.getTime() + time);
        return date;
    }

    /**
     * 对天数进行加减操作。
     *
     * @param d
     * @param offset
     * @return
     * @author yfyangzhen
     * @version 2012-12-26
     */
    public static Date changeDay(Date d, int offset) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(d);
        calendar.set(Calendar.DAY_OF_YEAR, (calendar.get(Calendar.DAY_OF_YEAR) + offset));
        return calendar.getTime();
    }

    /**
     * <p>计算开始日期 到 结束日期 总共有多少天</p>
     *
     * @param startDate
     * @param endDate
     * @return int
     */
    public static int daysBetween(Date startDate, Date endDate) {
        final int dayTime = 86400000;//一天的时间
        if (startDate == null || endDate == null) {
            return 0;
        }
        long ld1 = startDate.getTime();
        long ld2 = endDate.getTime();
        if (ld2 - ld1 < 0) {
            return 0;
        }
        int days = (int) ((ld2 - ld1) / dayTime);
        return days;
    }


    /**
     * 通过开始时间 结束时间 返回2天内（含开始时间和结束时间）的列表 时间格式为20171020
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static List<String> daysBetweenList(Date startDate, Date endDate, String formart) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(formart);
        List<String> daysList = new ArrayList<String>();
        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(startDate);
            while (calendar.getTime().compareTo(endDate) <= 0) {
                daysList.add(dateFormat.format(calendar.getTime()));
                calendar.add(Calendar.DAY_OF_MONTH, 1);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return daysList;
    }

    /**
     * @param date
     * @return Timestamp The Timestamp Object is such a 2012-09-11 10:40:25.0 style
     * note: the end of timestamp always is zero
     */
    public static Timestamp getZeroMillisecondTimestamp(Date date) {
        String loginTimeStr = AdsDateUtil.toStringYYYYMM_HH_mm_ss(date);
        return Timestamp.valueOf(loginTimeStr);
    }

    /**
     * @return 得到当前时间yyyyMMdd格式的时间字符串
     */
    public static int today() {
        String sDate = new SimpleDateFormat(formate).format(new Date());
        return Integer.valueOf(sDate);
    }

    /**
     * 判断开始日期是否大于截止日期
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static boolean compareDate(Date startDate, Date endDate) {
        if (null != startDate && null != endDate) {
            if (endDate.getTime() >= startDate.getTime()) {
                return true;
            }
        }
        return false;
    }


    public static Date addTimeByUnit(Date date, int field, int amount) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(field, amount);
        return calendar.getTime();
    }

    public static String getCurrentTimeStampStr() {
        Calendar calendar = Calendar.getInstance();
        Timestamp t = new Timestamp(calendar.getTimeInMillis());
        return t.toString();
    }

    public static Date getCurrentTime() {
        Calendar calendar = Calendar.getInstance();
        return calendar.getTime();
    }

    /**
     * 取得当月天数
     */
    public static int getCurrentMonthDay() {
        Calendar a = Calendar.getInstance();
        a.set(Calendar.DATE, 1);//把日期设置为当月第一天
        a.roll(Calendar.DATE, -1);//日期回滚一天，也就是最后一天
        int maxDate = a.get(Calendar.DATE);
        return maxDate;
    }

    /**
     * 取得指定日历所在月的天数
     */
    public static int getCurrentMonthDay(Calendar a) {
        a.set(Calendar.DATE, 1);//把日期设置为当月第一天
        a.roll(Calendar.DATE, -1);//日期回滚一天，也就是最后一天
        int maxDate = a.get(Calendar.DATE);
        return maxDate;
    }

    /**
     * 取得当月天数
     */
    public static Date getMonthFirstDay() {
        Calendar a = Calendar.getInstance();
        a.set(Calendar.DATE, 1);//把日期设置为当月第一天
        return a.getTime();
    }


    public static Date addDays(Date date, int amount) {
        return add(date, Calendar.DATE, amount);
    }

    private static Date add(Date date, int calendarField, int amount) {
        if (date == null) {
            throw new IllegalArgumentException("The date must not be null");
        } else {
            Calendar c = Calendar.getInstance();
            c.setTime(date);
            c.add(calendarField, amount);
            return c.getTime();
        }
    }

    public static class Day {

        public static Date getYesterday() {
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.DATE, -1);
            return calendar.getTime();
        }

    }

    public static Date parseDate(String dateStr, String... patterns) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        if (null != patterns && patterns.length > 0) {
            sdf.applyPattern(patterns[0]);
        }


        if (null == dateStr || "".equals(dateStr.trim())) {
            return null;
        }
        Date date = null;
        try {
            date = sdf.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return date;
    }

    public static Date parseDateFomartType(String dateStr, String format, String... patterns) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        if (null != patterns && patterns.length > 0) {
            sdf.applyPattern(patterns[0]);
        }


        if (null == dateStr || "".equals(dateStr.trim())) {
            return null;
        }
        Date date = null;
        try {
            date = sdf.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return date;
    }

    public static String format(Date date, String... patterns) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        if (null != patterns && patterns.length > 0) {
            sdf.applyPattern(patterns[0]);
        }

        if (null == date) {
            return null;
        }
        return sdf.format(date);
    }

    /**
     * 获取周
     *
     * @param date
     * @return 1-7 ,周一为第一天
     */
    public static Integer getWeek(Date date) {
        try {
            Calendar c = Calendar.getInstance();
            c.setTime(date);
            int h = c.get(Calendar.DAY_OF_WEEK) - 1;
            if (h == 0) h = 7;
            return h;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取小时数
     *
     * @param date
     * @return
     */
    public static Integer getHour(Date date) {
        try {
            Calendar c = Calendar.getInstance();
            c.setTime(date);
            int h = c.get(Calendar.HOUR_OF_DAY);
            return h;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 日期格式字符串转换成时间戳
     *
     * @return
     */
    public static String Date2TimeStamp() {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String nowDate = sdf.format(new Date());
            return String.valueOf(sdf.parse(nowDate).getTime() / 1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 获取前一天日期
     *
     * @param date
     * @return
     */
    public static String getYesterday(Date date) {
        try {
            Calendar calendar = Calendar.getInstance();//此时打印它获取的是系统当前时间
            calendar.add(Calendar.DATE, -1);    //得到前一天
            String yestedayDate = new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime());
            return yestedayDate;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 得到前days天的数据集合
     * @param date 当前时间
     * @param days 前几天
     * @return
     */
    public static List<String> getLastWeek(Date date, Integer days) {
        try {
            Calendar c = Calendar.getInstance();
            List<String> lastWeekList = new ArrayList<String>();
            for (int a = 1; a <= days; a++) {
                c.setTime(date);
                c.set(Calendar.DATE, c.get(Calendar.DATE) - a);
                lastWeekList.add(sf.format(c.getTime()));
            }
            return lastWeekList;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 得到几天前的时间
     *
     * @param d
     * @param day
     * @return
     */
    public static Date getDateBefore(Date d, int day) {
        Calendar now = Calendar.getInstance();
        now.setTime(d);
        now.set(Calendar.DATE, now.get(Calendar.DATE) - day);
        return now.getTime();
    }

    /**
     * 得到几天后的时间
     *
     * @param d
     * @param day
     * @return
     */
    public static Date getDateAfter(Date d, int day) {
        Calendar now = Calendar.getInstance();
        now.setTime(d);
        now.set(Calendar.DATE, now.get(Calendar.DATE) + day);
        return now.getTime();
    }

    /**
     * 获取两个日期相差的天数 date2 > date1
     * 通过日期（年月日）来比较
     */
    public static int differentDays(Date date1, Date date2)
    {
        Date mydate1 = date1;
        Date mydate2 = date2;
        int sum = 0;
        if(date2.compareTo(date1)<0){
            mydate1=date2;
            mydate2=date1;
        }

        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(mydate1);

        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(mydate2);
        int day1= cal1.get(Calendar.DAY_OF_YEAR);
        int day2 = cal2.get(Calendar.DAY_OF_YEAR);

        int year1 = cal1.get(Calendar.YEAR);
        int year2 = cal2.get(Calendar.YEAR);
        if(year1 != year2)   //同一年
        {
            int timeDistance = 0 ;
            for(int i = year1 ; i < year2 ; i ++)
            {
                if(i%4==0 && i%100!=0 || i%400==0)    //闰年
                {
                    timeDistance += 366;
                }
                else    //不是闰年
                {
                    timeDistance += 365;
                }
            }

            sum= timeDistance + (day2-day1) ;
        } else    //不同年
        {
            System.out.println("判断day2 - day1 : " + (day2-day1));
            sum= day2-day1;
        }
        if(date2.compareTo(date1)<0){
            return 0-sum;
        }else{
            return sum;
        }
    }

    /**
     * 获取日期所在的季度
     */
    public static int getQuarterByDate(Date date){

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        Integer remarkMonth = calendar.get(Calendar.MONTH)+1;
        // remark_quarter 自动计算，根据投放开始时间，取第几季度
        Integer remarkQuarter = (remarkMonth-1)/3+1;
        return remarkQuarter.intValue();
    }


    public static void main(String[] args) {

        System.out.println(getLastWeek(new Date(),4));
        System.out.println(Date2TimeStamp());
        System.out.println(getWeek(new Date()));

        System.out.println(getCurrentMonthDay(Calendar.getInstance()));

        System.out.println(getQuarterByDate(new Date()));
    }




}